package com.aosgame;

import android.graphics.Bitmap;
import android.graphics.Rect;

import com.androidgame.fx.Graphics;
import com.androidgame.fx.Input.TouchEvent;
import com.androidgame.fx.ScreenConfig;

public class DrtPad {

	private Bitmap 	padImage;
	private Bitmap 	stickImage;
	private Rect	padArea;
	private Rect	stickArea;
	private Rect	stickBaseArea;
	private Player	player;
	private boolean	touched;
	private int 	touchPointer;
	
	public DrtPad(Player player) {
		this.player = player;
		
		padImage = Assets.drtPad;
		stickImage = Assets.drtStick;
		int scrWidth = ScreenConfig.virtualScreenWidth;
		int scrHeight = ScreenConfig.virtualScreenHeight;
		int left = (int)(scrWidth * 0.05);
		int bottom = (int)(scrHeight * 0.95);
		padArea = new Rect(left, bottom - padImage.getHeight(), left + padImage.getWidth(), bottom);
		
		left = padArea.centerX() - stickImage.getWidth() / 2;
		bottom = padArea.centerY() + stickImage.getHeight() / 2;
		stickBaseArea = new Rect(left, bottom - stickImage.getHeight(), left + stickImage.getWidth(), bottom);
		stickArea = new Rect(stickBaseArea);
		
		touchPointer = -1;
	}

	public boolean touchDown(TouchEvent event) {
		if(ptInCircle(padArea, event.x, event.y)) {
			touchPointer = event.pointer;
			touched = true;
			int left = event.x - stickArea.width() / 2;
			int top = event.y - stickArea.height() / 2;
			stickArea.set(left, top, left + stickArea.width(), top + stickArea.height());
			
			if(!compareState(Player.STATE_ATTACK)) {
				player.angle = getAngle(stickBaseArea.centerX(), stickBaseArea.centerY(), event.x, event.y);
				player.addState(Player.STATE_WALK);
				player.setAnimation(Entity.ANI_WALK);	
			}
		}
		return false;
	}

	public boolean touchDragged(TouchEvent event) {
		if(event.pointer != touchPointer) return false;
		
		if(touched == true) {
			int left, top;
			float angle;
			if(ptInCircle(padArea, event.x, event.y)) {
				left = event.x - stickArea.width() / 2;
				top = event.y - stickArea.height() / 2;
				angle = getAngle(stickBaseArea.centerX(), stickBaseArea.centerY(), event.x, event.y);
			} else {
				angle = getAngle(stickBaseArea.centerX(), stickBaseArea.centerY(), event.x, event.y);
				left = padArea.centerX() + (int)(Math.cos(angle) * (padArea.width() / 2)) - stickArea.width() / 2;
				top = padArea.centerY() + (int)(-Math.sin(angle) * (padArea.height() / 2)) - stickArea.height() / 2;
			}
			stickArea.set(left, top, left + stickArea.width(), top + stickArea.height());
			
			if(!compareState(Player.STATE_ATTACK)) {
				player.angle = angle;
				player.addState(Player.STATE_WALK);
				player.setAnimation(Entity.ANI_WALK);
			}
		}
		return false;
	}

	public boolean touchUp(TouchEvent event) {
		if(event.pointer == touchPointer){
			touched = false;
			stickArea.set(stickBaseArea);
			
			if(!compareState(Player.STATE_ATTACK)) {
				player.setAnimation(Entity.ANI_IDLE);
			}
			player.removeState(Player.STATE_WALK);
			touchPointer = -1;
		}
		return false;
	}
	
	public void present(Graphics g) {
		g.drawBitmap(padImage, padArea.left, padArea.top);
		g.drawBitmap(stickImage, stickArea.left, stickArea.top);
	}
	
	private float getAngle(int srcX, int srcY, int destX, int destY) {
		float		x, y;
		float		angle;

		x = destX - srcX;
		y = destY - srcY;

		if(x == 0.0f) x = 0.000001f;
		angle = (float)Math.atan(-y / x);	
		if(x < 0) angle += Math.PI;
		if(destX >= srcX && destY >= srcY) angle += 2 * Math.PI;

		return angle;		
	}
	
	private boolean ptInCircle(Rect circle, int x, int y) {
		int radius = circle.width() / 2;
		
		int distance = (int)Math.sqrt((circle.centerX() - x) * (circle.centerX() - x) + 
				(circle.centerY() - y) * (circle.centerY() - y)); 
		
		if(distance < radius) {
			return true;
		}
		return false;
	}
	
	public boolean compareState(byte state) {
		if((player.state & state) == state) {
			return true;
		}
		return false;
	}
}
